package utils
{
	import flash.display3D.Context3D;
	import flash.display3D.Program3D;
	import flash.display3D.textures.Texture;
	import flash.geom.Matrix3D;
	import flash.geom.Vector3D;
	
	import utils.math.Quaternion;
	
	public class EntityAbsolute3D extends Entity3D
	{
		private var _absoluteX:Vector3D;
		private var _absoluteY:Vector3D;
		private var _absoluteZ:Vector3D;
		
		private var _absoluteRotationX:Number = 0;
		private var _absoluteRotationY:Number = 0;
		private var _absoluteRotationZ:Number = 0;
		
		public function EntityAbsolute3D(modeldata:String=null, mycontext:Context3D=null, myshader:Program3D=null, mytexture:Texture=null, modelscale:Number=1, data_is_zxy:Boolean=true, texture_flip:Boolean=true)
		{
			super(modeldata, mycontext, myshader, mytexture, modelscale, data_is_zxy, texture_flip);
			_absoluteX = Vector3D.X_AXIS.clone();
			_absoluteY = Vector3D.Y_AXIS.clone();
			_absoluteZ = Vector3D.Z_AXIS.clone();
		}
		
		
		override public function updateTransformFromValues():void
		{
			_transform.identity();
			//_transform.appendRotation(_absoluteRotationX, _absoluteX);
			//_transform.appendRotation(_absoluteRotationY, _absoluteY);
			//_transform.appendRotation(_absoluteRotationZ, _absoluteZ);
			_transform.append(transformRoation);
			_transform.appendScale(_scaleX, _scaleY, _scaleZ);
			_transform.appendTranslation(_x, _y, _z);
			_transformNeedsUpdate = false;
			
			/*var Q0:Quaternion=new Quaternion;   //创建一个4元数;
			Q0.fromMatrix(_transform);      //将现转矩阵转换为4元数;
			//trace(Q0.x,Q0.y,Q0.z,Q0.w)
			getW(Q0.x,Q0.y,Q0.z,Q0.w)*/
		}
		private function getW(a:Number,b:Number,c:Number,d:Number):void{
			//trace(a,b,c,d,a*a+b*b+c*c+d*d)
		}
		private var transformRoation:Matrix3D = new Matrix3D;
		

		public function get absoluteRotationX():Number
		{
			return _absoluteRotationX;
		}

		public function set absoluteRotationX(value:Number):void
		{
			_absoluteRotationX = value;
			transformRoation.appendRotation(_absoluteRotationX, _absoluteX);
			//rotationByAxis(_absoluteX,_absoluteY,value);
			//rotationByAxis(_absoluteX,_absoluteZ,value);
			_transformNeedsUpdate = true;
		}

		public function get absoluteRotationY():Number
		{
			return _absoluteRotationY;
		}

		public function set absoluteRotationY(value:Number):void
		{
			_absoluteRotationY = value;
			transformRoation.appendRotation(_absoluteRotationY, _absoluteY);
			//rotationByAxis(_absoluteY,_absoluteX,value);
			//rotationByAxis(_absoluteY,_absoluteZ,value);
			_transformNeedsUpdate = true;
		}

		public function get absoluteRotationZ():Number
		{
			return _absoluteRotationZ;
		}

		public function set absoluteRotationZ(value:Number):void
		{
			_absoluteRotationZ = value;
			transformRoation.appendRotation(_absoluteRotationZ, _absoluteZ);
			//rotationByAxis(_absoluteY,_absoluteY,value);
			//rotationByAxis(_absoluteY,_absoluteX,value);
			_transformNeedsUpdate = true;
		}
		
		private function rotationByAxis(axis:Vector3D,targetVecter:Vector3D,angle:Number):void{
			var cos:Number = Math.cos(angle * Math.PI / 180);
			var sin:Number = Math.sin(angle * Math.PI / 180);
			
			var x1:Number = cos + (1 - cos) * axis.x * axis.x;
			var y1:Number = (1 - cos) * axis.x * axis.y + axis.z * sin;
			var z1:Number = (1 - cos) * axis.x * axis.z - axis.y * sin;
			
			var x2:Number = (1 - cos) * axis.x * axis.y - axis.z * sin;
			var y2:Number = cos + (1 - cos) * axis.y * axis.y;
			var z2:Number = (1 - cos) * axis.y * axis.z + axis.x * sin;
			
			var x3:Number = (1 - cos) * axis.x * axis.z + axis.y * sin;
			var y3:Number = (1 - cos) * axis.y * axis.z + axis.x * sin;
			var z3:Number = cos + (1 - cos) * axis.z * axis.z;
			
			var tx:Number = targetVecter.x * x1 + targetVecter.y * y1 + targetVecter.z * z1;
			var ty:Number = targetVecter.x * x2 + targetVecter.y * y2 + targetVecter.z * z2;
			var tz:Number = targetVecter.x * x3 + targetVecter.y * y3 + targetVecter.z * z3;
			
			targetVecter.x = tx;
			targetVecter.y = ty;
			targetVecter.z = tz;
		}


	}
}